package com.glodon.paas.account.security.openid.association;

import org.openid4java.association.Association;
import org.openid4java.association.AssociationException;
import org.openid4java.server.ServerAssociationStore;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;

import java.util.Random;

/**
 * @author Don Li
 */
public class RedisServerAssociationStore implements ServerAssociationStore {

    private static final String KEY_PREFIX = "OPENID:ASSOC:";

    private Random random = new Random(System.currentTimeMillis());

    private RedisTemplate<String, Association> template;

    private JedisPool pool;

    public RedisServerAssociationStore(RedisTemplate<String, Association> template, JedisPool pool) {
        this.template = template;
        this.pool = pool;
    }

    @Override
    public Association generate(String type, int expiryIn) throws AssociationException {
        String handle = Long.toHexString(random.nextLong());
        Association association = Association.generate(type, handle, expiryIn);

        final Jedis jedis = pool.getResource();
        Transaction transaction = jedis.multi();
        String key = KEY_PREFIX + handle;
        transaction.set(key.getBytes(), new JdkSerializationRedisSerializer().serialize(association));
        transaction.expire(key, expiryIn);
        transaction.exec();
        pool.returnResource(jedis);

        return association;
    }

    @Override
    public Association load(String handle) {
        return template.opsForValue().get(KEY_PREFIX + handle);
    }

    @Override
    public void remove(String handle) {
        template.delete(KEY_PREFIX + handle);
    }
}
